﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using WebCrawlerTools.page;
using WebCrawlerTools.search;
using WebCrawlerTools.data;
using System.Windows.Forms;
using System.Web;

namespace WebCrawlerTools
{
    class SEngine
    {
        private static SEngine pThis;

        private Page page;
        private INet net;
        private String source;
        private ArrayList subPageUriList;
        private int subPageIndex;
        public String Source
        {
            get { return source; }
            set { source = value; }
        }

        private SResult sResult;

        private STemplate sTemplate;

        public SEngine()
        {
            pThis = this;
            net = new MyWebBrower();
            net.Done += new EventHandler(this.OnOpen);
            AllPageComplate += new EventHandler(this.StartSubPage);
            subPageIndex = -1;
        }

        public static SEngine getSEngine()
        {
            if (pThis == null)
            {
                pThis = new SEngine();
            }
            return pThis;
        }

        public void Start()
        {
            if (null != page)
            {
                dataCenter.DataInfo.Clear();
                Net.OpenUri(page.Url);
                Log.Inst().Write(page.Url);
            }
        }

        public bool GoNextPage()
        {
            bool retval = false;
            if (null != page && null != page.Loop )
            {
                if (page.PageType == PPageType.HOME_PAGE)
                {
                    if (page.Loop.Template == "")
                    {
                        return retval;
                    }
                    sTemplate = new STemplate(page.Loop.Template);
                    Result = new SResult();
                    Result.Title = sTemplate.getTitle();
                    analysis();
                    if (Result.Data.Count > 0)
                    {
                        SLine line = (SLine)Result.Data[0];
                        string newurl = (String)line.Data[0];
                        newurl = HttpUtility.HtmlDecode(newurl);
                        if (page.Loop.Type == LoopType.URL)
                        {
                            string oldurl = net.Uri.AbsoluteUri;

                            if (newurl.StartsWith("http://"))
                            {

                            }
                            else if (newurl.StartsWith("/"))
                            {
                                newurl = "http://" + net.Uri.Host + newurl;
                            }
                            else
                            {
                                newurl = oldurl.Substring(0, oldurl.LastIndexOf("/") + 1) + newurl;
                            }
                            if (!dataCenter.DataInfo.IsExist(newurl))
                            {
                                net.OpenUri(newurl);

                                Log.Inst().Write(newurl);
                                retval = true;
                            }
                        }
                    }
                    else
                    {
                        if (null != AllPageComplate)
                        {
                            AllPageComplate.Invoke(this, new EventArgs());
                        }
                    }
                }
                else if (page.PageType == PPageType.SUB_PAGE)
                {
                    if (null != subPageUriList)
                    {
                        if (null != subPageUriList && subPageIndex < subPageUriList.Count)
                        {
                            String newurl = (String)subPageUriList[subPageIndex++];
                            net.OpenUri(newurl);
                            Log.Inst().Write(newurl);
                        }
                    }

                }
            }
            return retval;
        }

        public void StartSubPage(object sender, EventArgs e)
        {
            subPageUriList = dataCenter.DataInfo.GetSubPageUrlList();
            dataCenter.DataInfo.Clear();
            subPageIndex = 0;
            if (null != subPageUriList && subPageUriList.Count > subPageIndex)
            {
                String newurl = (String)subPageUriList[subPageIndex++];
                net.OpenUri(newurl);
                Log.Inst().Write(newurl);
            }
        }

        public void OnOpen(object sender, EventArgs e)
        {
            this.source = Net.HtmlSrc();
            sTemplate = new STemplate(page.Template.Replace("\n", "\r\n"));
            Result = new SResult();
            Result.Title = sTemplate.getTitle();
            analysis();
            Log.Inst().Write(Result.ToString());
            dataCenter.DataInfo.AddPageData(net.Uri.AbsoluteUri,Result);
        }

        public void analysis()
        {
            SPart sPart = new SPart();
            int startPos= 0;
            while (sPart.FindPart(startPos))
            {
                Result.Data.Add(sPart.getValues());
                startPos = sPart.EndPos+1;
            }
        }

        public SResult Result
        {
            get
            {
                return sResult;
            }
            set
            {
                sResult = value;
            }
        }

        public STemplate Template
        {
            get
            {
                return sTemplate;
            }
            set
            {
                sTemplate = value;
            }
        }

        public WebCrawlerTools.page.Page Page
        {
            get
            {
                return page;
            }
            set
            {
                page = value;
            }
        }

        public INet Net
        {
            get
            {
                return net;
            }
        }

        public WebCrawlerTools.data.DataCenter DataCenter
        {
            get
            {
                return dataCenter;
            }
            set
            {
                dataCenter = value;
            }
        }

        private DataCenter dataCenter;

        public event EventHandler AllPageComplate;
    }
}
